'''
Created on Apr 19, 2012

@author: root
'''

# TO DO
# - Notify User that Filesystem exists.  Maybe ask if it should be leveraged?




from Log_FS import Log_FS
import threading
import ssh
import logging


class Filesystem:
    
    
    Users = []
    Nodes = [] 
    Disks = []
    Log = []
    clusterDiskInfo = []
    clusterUserInfo = []
    sshReturns = []
    fsLog = ""
    installUser = ""
    installPW = ""
    mapredUser = ""
    mapredPW = ""
    hdfsUser = ""
    hdfsPW = ""
    
    
    def sshExec(self,cmd,node,disk,callingModule):
        try:
            sshCon = ssh.Connection(node.get_hostName(), username=self.installUser, password=self.installPW)
            (execStatus,execReturn) = sshCon.executeSt(cmd)
        except Exception, err:
            exception = "ERROR: Trouble with SSH Connection to "+node.get_hostName()+" : "+str(err)
            execReturn = exception
            execStatus = 1
            #self.fsLog.exception(exception)
        log_FS = Log_FS()
        log_FS.add(node.get_hostName(),callingModule,cmd,execReturn,disk.get_fsType(),disk.get_deviceName(),execStatus)
        self.Log.add_Log_FS(log_FS)

      
            
    def install(self):
        
        print "---------------------------------------"
        print "- Creating Filesystems on All Devices -"
        print "---------------------------------------"
        threadCount = 0
        Threads = []
     
        for node in self.Nodes:
            for disk in node.get_Disks():
                mkfsCMD = "sudo /sbin/mkfs -t " + disk.get_fsType() + " " + disk.get_deviceName()
                Threads.append(threading.Thread(target=self.sshExec,args=(mkfsCMD,node,disk,"installFS")))
                Threads[threadCount].daemon=True
                Threads[threadCount].start()
                threadCount = threadCount + 1
        for thread in Threads:
            thread.join()
        ver = self.verify()
        return (ver)        

    def verify(self):
        status = 0
        threadCount = 0
        Threads = []
        diskData = []
        for node in self.Nodes:
            for disk in node.get_Disks():
                verifyCMD = "sudo file -sL " + disk.get_deviceName()
                Threads.append(threading.Thread(target=self.sshExec,args=(verifyCMD,node,disk,"verifyFS")))
                Threads[threadCount].daemon=True
                Threads[threadCount].start()     
                threadCount = threadCount + 1
        for thread in Threads:
            thread.join()
        fsLogs = self.Log.get_Log_FS()    
        for log in fsLogs:
            
            if (log.get_module() == "installFS") and (log.get_statusCode() == 0):
                print "INSTALLFS: Successful FS install on "+ log.get_nodeName()+":"+log.get_diskDevice()
            elif (log.get_module() == "installFS") and (log.get_statusCode() == 1):
                print "INSTALLFS: MKFS Failed on "+ log.get_nodeName()+":"+log.get_diskDevice()
            
            elif (log.get_module() == "verifyFS") and (log.get_statusCode() != 0):
                print "VERIFYFS: Error: No Filesystem on "+ log.get_nodeName()+":"+log.get_diskDevice()
                status = 1
                log.set_statusCode(1L)
            elif (log.get_module() == "verifyFS") and (log.get_statusCode() == 0) and (str(log.get_fsType()).upper() in str(log.get_results()).upper()):
                print "VERIFYFS: A Filesystem is Available on "+ log.get_nodeName()+":"+log.get_diskDevice()
                status = 0
            elif (log.get_module() == "verifyFS") and (log.get_statusCode() == 0) and ("FILESYSTEM" in str(log.get_results()).upper()):
                print "VERIFYFS: Incorrect Filesystem Type on "+ log.get_nodeName()+":"+log.get_diskDevice()
                status = 1
                log.set_statusCode(1L)
            elif (log.get_module() == "verifyFS") and (log.get_statusCode() == 0) and ("ERROR" in str(log.get_results()).upper()):
                print "VERIFYFS: Could Not Verify Filesystem on "+ log.get_nodeName()+":"+log.get_diskDevice()
                status = 1
                log.set_statusCode(1L)
            elif (log.get_module() == "verifyFS") and (log.get_statusCode() == 0) and not("FILESYSTEM" in str(log.get_results()).upper()):
                print "VERIFYFS: Could Not place Filesystem on  "+ log.get_nodeName()+":"+log.get_diskDevice()
                status = 1
                log.set_statusCode(1L)
            elif (log.get_module() == "installFS") and (log.get_statusCode() == 1) and ("EXISTING" in str(log.get_results()).upper()):
                print "INSTALLFS: Filesystem already present on Device " + log.get_nodeName()+":"+log.get_diskDevice()
                status = 1
                log.set_statusCode(1L)
            
            if (log.get_module() == "verifyFS") and (status == 1):
                for node in self.Nodes:
                    for disk in node.get_Disks():
                        if (log.get_nodeName()==node.get_hostName()) and (log.get_diskDevice()==disk.get_deviceName()):
                            print "CHANGED STATUS"
                            disk.set_fsStatus(1)    
        return status
  
    
    def mount(self,mountPoint,dataDir):
        
        threadCount = 0
        Threads = []
        
        print "-------------------------------"
        print "Mounting new Filesystems"
        print "-------------------------------"  
        for node in self.Nodes:
            diskCnt = 0
            for disk in node.get_Disks():
                diskCnt = diskCnt + 1
                if (disk.get_fsStatus() == 0):
                    mountDir = str(mountPoint) + str(dataDir) + str(diskCnt)
                    mkdirCMD = "sudo mkdir -p " + mountDir
                    self.sshExec(mkdirCMD,node,disk,"mountFS")
                    mountCMD = "sudo mount "+ str(disk.get_deviceName()) + " " + str(mountDir)
                    Threads.append(threading.Thread(target=self.sshExec,args=(mountCMD,node,disk,"mountFS")))
                    Threads[threadCount].daemon=True
                    Threads[threadCount].start()
                    threadCount = threadCount + 1
                else:
                    print "No Filesystem available to mount"
       
            for thread in Threads:
                thread.join()
           
        
    def set_Users(self):
        for user in self.Users:
            if user.get_role() == "r":
                self.installUser = user.get_userName()
                self.installPW = user.get_password()
            elif user.get_role() == "m":
                self.mapredUser = user.get_userName()
                self.mapredPW = user.get_password()
            elif user.get_role() == "h":
                self.hdfsUser = user.get_userName()
                self.hdfsPW = user.get_password()
                 
                
    def __init__(self,Nodes,Users,Log):
        self.Users = Users
        self.Nodes = Nodes
        self.set_Users()
        self.Log = Log       
        #logging.basicConfig(level=logging.ERROR)
        self.fsLog = logging.getLogger('Filesystem')
        